package cn.cuilan.client.core;

import cn.cuilan.common.client.ProtocolMessageClient;
import cn.cuilan.common.entity.ProtocolMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.net.InetSocketAddress;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class ClientHelper {

    @Value("${net.server.host}")
    private String host;

    @Value("${net.server.port}")
    private int port;

    static int sendTimeoutSecond = 30;

    private InetSocketAddress inetSocketAddress;

    @Resource
    private ClientPool<ProtocolMessage> clientPool;

    @PostConstruct
    public void init() {
        inetSocketAddress = new InetSocketAddress(host, port);
    }

    /**
     * 基于Netty发送消息
     *
     * @param request 客户端请求消息
     * @return 返回服务端响应消息
     */
    public ProtocolMessage doSendWithNetty(ProtocolMessage request) {
        ProtocolMessageClient<ProtocolMessage> client = null;
        try {
            client = clientPool.getClient(() -> createClient(inetSocketAddress));
            request.pack();

            NetClientMessageProcessor messageProcessor = (NetClientMessageProcessor) client.getMessageHandler().getMessageListeners().get(0);
            messageProcessor.reset();
            client.send(request, sendTimeoutSecond, TimeUnit.SECONDS);

            ProtocolMessage response = messageProcessor.waitMsg();
            response.unpack();
            return response;
        } catch (Exception e) {
            e.printStackTrace();
            log.info("客户端发送消息异常", e);
            throw new RuntimeException();
        } finally {
            if (client != null) {
                clientPool.returnClient(client);
            }
        }
    }

    /**
     * 创建客户端
     *
     * @param inetSocketAddress 连接信息
     * @return 返回私有协议客户端
     */
    public ProtocolMessageClient<ProtocolMessage> createClient(InetSocketAddress inetSocketAddress) {
        // 1.创建私有协议客户端
        ProtocolMessageClient<ProtocolMessage> client = new ProtocolMessageClient<>(inetSocketAddress);
        // 2.添加监听器
        client.addMessageListener(new NetClientMessageProcessor());
        // 3.配置客户端
        client.getConfiguration().replyOnError();
        // 4.初始化
        client.init();
        try {
            // 5.连接
            client.connect();
        } catch (InterruptedException e) {
            log.info("客户端连接失败, host: {}, port: {}", inetSocketAddress.getHostString(), inetSocketAddress.getPort());
            throw new RuntimeException();
        }
        return client;
    }

}
